function matlab_verify_schedule(case_name)
% 使用MATLAB验证C语言调度结果的V_stay计算
% 输入: case_name (如 'Conv_Case0')

if nargin < 1
    case_name = 'Conv_Case0';  % 默认案例
end

fprintf('=== MATLAB验证C语言调度结果：%s ===\n', case_name);

%% 1. 加载原始数据
fprintf('步骤1: 加载原始图数据...\n');
try
    % 加载节点和边数据
    nodes_file = sprintf('../data/CSV-version/%s_Nodes.csv', case_name);
    edges_file = sprintf('../data/CSV-version/%s_Edges.csv', case_name);
    
    nodes_table = readtable(nodes_file);
    edges_table = readtable(edges_file);
    
    % 创建编码映射 (与C代码一致) - 在创建图对象之前
    nodes_table.OpCode = double(categorical(nodes_table.Op));
    nodes_table.TypeCode = double(categorical(nodes_table.Type));
    
    % 创建图对象
    G = digraph(edges_table.StartNodeId + 1, edges_table.EndNodeId + 1, [], nodes_table);
    fprintf('  ✅ 图数据加载成功: %d 节点, %d 边\n', numnodes(G), numedges(G));
    
    categories_op = categories(categorical(nodes_table.Op));
    categories_type = categories(categorical(nodes_table.Type));
    
    code_map.op.ALLOC = find(strcmp('ALLOC', categories_op), 1);
    code_map.op.FREE = find(strcmp('FREE', categories_op), 1);
    code_map.type.L1 = find(strcmp('L1', categories_type), 1);
    code_map.type.UB = find(strcmp('UB', categories_type), 1);
    code_map.type.L0A = find(strcmp('L0A', categories_type), 1);
    code_map.type.L0B = find(strcmp('L0B', categories_type), 1);
    code_map.type.L0C = find(strcmp('L0C', categories_type), 1);
    
    fprintf('  ✅ 编码映射创建完成\n');
    
catch ME
    fprintf('  ❌ 数据加载失败: %s\n', ME.message);
    return;
end

%% 2. 读取C语言调度结果
fprintf('\n步骤2: 读取C语言调度结果...\n');
try
    c_schedule_file = sprintf('result/Problem1/%s_schedule.txt', case_name);
    c_summary_file = sprintf('result/Problem1/%s_summary.txt', case_name);
    
    % 读取调度序列 (转换为MATLAB 1-based索引)
    c_schedule = readmatrix(c_schedule_file) + 1;
    fprintf('  ✅ C语言调度序列读取成功: %d 个节点\n', length(c_schedule));
    
    % 读取C语言报告的结果
    if exist(c_summary_file, 'file')
        summary_text = fileread(c_summary_file);
        
        % 解析关键数值
        initial_match = regexp(summary_text, 'Initial V_stay:\s*(\d+)', 'tokens');
        phase1_match = regexp(summary_text, 'Phase 1 V_stay:\s*(\d+)', 'tokens');
        final_match = regexp(summary_text, 'Final V_stay:\s*(\d+)', 'tokens');
        
        c_initial_vstay = str2double(initial_match{1}{1});
        c_phase1_vstay = str2double(phase1_match{1}{1});  
        c_final_vstay = str2double(final_match{1}{1});
        
        fprintf('  ✅ C语言报告的结果:\n');
        fprintf('    初始V_stay: %d\n', c_initial_vstay);
        fprintf('    阶段一V_stay: %d\n', c_phase1_vstay);
        fprintf('    最终V_stay: %d\n', c_final_vstay);
    else
        fprintf('  ⚠️  未找到C语言摘要文件\n');
        c_final_vstay = NaN;
    end
    
catch ME
    fprintf('  ❌ C语言结果读取失败: %s\n', ME.message);
    return;
end

%% 3. 基本完整性检查
fprintf('\n步骤3: 基本完整性检查...\n');

% 长度检查
if length(c_schedule) ~= numnodes(G)
    fprintf('  ❌ 调度长度不匹配: 期望%d, 实际%d\n', numnodes(G), length(c_schedule));
    return;
else
    fprintf('  ✅ 调度长度正确: %d\n', length(c_schedule));
end

% 唯一性检查
unique_nodes = unique(c_schedule);
if length(unique_nodes) ~= length(c_schedule)
    fprintf('  ❌ 调度中有重复节点\n');
    return;
else
    fprintf('  ✅ 调度中所有节点唯一\n');
end

% 范围检查
if min(c_schedule) < 1 || max(c_schedule) > numnodes(G)
    fprintf('  ❌ 调度中有无效节点ID: 范围[%d, %d]\n', min(c_schedule), max(c_schedule));
    return;
else
    fprintf('  ✅ 所有节点ID有效: 范围[%d, %d]\n', min(c_schedule), max(c_schedule));
end

%% 4. MATLAB重新计算V_stay
fprintf('\n步骤4: MATLAB重新计算V_stay...\n');
try
    tic;
    [matlab_vstay, matlab_history] = calculate_max_vstay(c_schedule, G, code_map, nodes_table);
    calculation_time = toc;
    
    fprintf('  ✅ MATLAB计算完成 (耗时: %.3f 秒)\n', calculation_time);
    fprintf('  📊 MATLAB计算的V_stay峰值: %d\n', matlab_vstay);
    
catch ME
    fprintf('  ❌ MATLAB计算失败: %s\n', ME.message);
    return;
end

%% 5. 结果对比和验证
fprintf('\n步骤5: 结果验证...\n');
fprintf('===============================================\n');
fprintf('             结果对比验证\n');
fprintf('===============================================\n');

if ~isnan(c_final_vstay)
    fprintf('C语言报告的V_stay:    %d\n', c_final_vstay);
    fprintf('MATLAB重算的V_stay:   %d\n', matlab_vstay);
    fprintf('数值差异:            %d\n', matlab_vstay - c_final_vstay);
    
    if matlab_vstay == c_final_vstay
        fprintf('验证结果:            ✅ 完全一致！\n');
        verification_status = 'PASS';
    else
        fprintf('验证结果:            ❌ 不一致！\n');
        verification_status = 'FAIL';
    end
else
    fprintf('MATLAB计算的V_stay:   %d\n', matlab_vstay);
    verification_status = 'NO_COMPARISON';
end

%% 6. 详细分析
fprintf('\n步骤6: 详细V_stay分析...\n');

% 找到峰值位置
[max_vstay, peak_step] = max(matlab_history);
fprintf('峰值分析:\n');
fprintf('  峰值V_stay: %d\n', max_vstay);
fprintf('  峰值位置: 步骤 %d (节点 %d)\n', peak_step, c_schedule(peak_step) - 1);
fprintf('  初始V_stay: %d\n', matlab_history(1));
fprintf('  最终V_stay: %d\n', matlab_history(end));

% 显示峰值附近的情况
fprintf('\n峰值附近的V_stay变化:\n');
start_idx = max(1, peak_step - 3);
end_idx = min(length(matlab_history), peak_step + 3);
for i = start_idx:end_idx
    marker = '';
    if i == peak_step
        marker = ' ← 峰值';
    end
    fprintf('  步骤%4d (节点%4d): V_stay = %6d%s\n', ...
           i, c_schedule(i) - 1, matlab_history(i), marker);
end

% 统计信息
fprintf('\nV_stay统计信息:\n');
fprintf('  平均值: %.1f\n', mean(matlab_history));
fprintf('  标准差: %.1f\n', std(matlab_history));
fprintf('  变异系数: %.2f%%\n', std(matlab_history)/mean(matlab_history)*100);

%% 7. L0约束验证
fprintf('\n步骤7: L0约束验证...\n');
try
    is_valid = is_l0_schedule_valid(c_schedule, G, code_map, nodes_table);
    if is_valid
        fprintf('L0约束验证: ✅ 满足所有L0存储器约束\n');
    else
        fprintf('L0约束验证: ❌ 违反L0存储器约束\n');
    end
catch ME
    fprintf('L0约束验证: ❌ 验证失败: %s\n', ME.message);
end

%% 8. 生成验证报告
fprintf('\n步骤8: 生成验证报告...\n');
report_file = sprintf('result/Problem1/%s_matlab_verification.txt', case_name);
try
    fid = fopen(report_file, 'w');
    
    fprintf(fid, '=== MATLAB验证C语言调度结果报告 ===\n');
    fprintf(fid, '案例名称: %s\n', case_name);
    fprintf(fid, '验证时间: %s\n', datestr(now));
    fprintf(fid, '验证状态: %s\n', verification_status);
    fprintf(fid, '\n数值对比:\n');
    if ~isnan(c_final_vstay)
        fprintf(fid, '  C语言V_stay: %d\n', c_final_vstay);
    end
    fprintf(fid, '  MATLAB V_stay: %d\n', matlab_vstay);
    fprintf(fid, '  计算耗时: %.3f 秒\n', calculation_time);
    
    fprintf(fid, '\n详细分析:\n');
    fprintf(fid, '  峰值: %d (步骤 %d)\n', max_vstay, peak_step);
    fprintf(fid, '  平均值: %.1f\n', mean(matlab_history));
    fprintf(fid, '  标准差: %.1f\n', std(matlab_history));
    
    fclose(fid);
    fprintf('  ✅ 验证报告已保存到: %s\n', report_file);
catch ME
    fprintf('  ❌ 报告保存失败: %s\n', ME.message);
end

%% 9. 可视化 (可选)
fprintf('\n步骤9: 生成可视化图表...\n');
try
    figure('Position', [100, 100, 1200, 600]);
    
    subplot(1, 2, 1);
    steps = 1:length(matlab_history);
    plot(steps, matlab_history, 'b-', 'LineWidth', 1.5);
    hold on;
    plot(peak_step, max_vstay, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'red');
    xlabel('执行步骤');
    ylabel('V_{stay}');
    title(sprintf('%s - V_{stay} 变化曲线', case_name));
    grid on;
    legend('V_{stay}轨迹', '峰值', 'Location', 'best');
    
    subplot(1, 2, 2);
    histogram(matlab_history, 50, 'FaceAlpha', 0.7);
    xline(matlab_vstay, 'r-', 'LineWidth', 2, 'Label', sprintf('峰值: %d', matlab_vstay));
    xline(mean(matlab_history), 'g--', 'LineWidth', 1.5, 'Label', sprintf('均值: %.0f', mean(matlab_history)));
    xlabel('V_{stay}');
    ylabel('频次');
    title('V_{stay} 分布直方图');
    legend('Location', 'best');
    
    sgtitle(sprintf('MATLAB验证结果: %s (状态: %s)', case_name, verification_status));
    
    % 保存图表
    fig_file = sprintf('result/Problem1/%s_matlab_verification.png', case_name);
    saveas(gcf, fig_file);
    fprintf('  ✅ 可视化图表已保存到: %s\n', fig_file);
    
catch ME
    fprintf('  ❌ 可视化失败: %s\n', ME.message);
end

fprintf('\n=== MATLAB验证完成 ===\n');

end

%% 辅助函数需要确保存在
% 如果calculate_max_vstay函数不存在，这里提供一个实现
function [max_v, history] = calculate_max_vstay(schedule, G, code_map, nodes_table)
    v_stay = 0; 
    max_v = 0;
    
    if isempty(schedule)
        history = [];
        return; 
    end
    
    history = zeros(1, length(schedule));
    
    for i = 1:length(schedule)
        node_id = schedule(i);
        
        % 直接从nodes_table获取节点信息（更可靠）
        if nargin >= 4 && ~isempty(nodes_table)
            op = nodes_table.OpCode(node_id); 
            type = nodes_table.TypeCode(node_id);
            size_val = nodes_table.Size(node_id);
        else
            % 回退到使用G.Nodes（如果可用）
            op = G.Nodes.OpCode(node_id); 
            type = G.Nodes.TypeCode(node_id);
            size_val = G.Nodes.Size(node_id);
        end
        
        % 只考虑L1和UB类型的内存占用
        if isequal(type, code_map.type.L1) || isequal(type, code_map.type.UB)
            if isequal(op, code_map.op.ALLOC)
                v_stay = v_stay + size_val;
            elseif isequal(op, code_map.op.FREE)
                v_stay = v_stay - size_val; 
            end
        end
        
        if v_stay > max_v
            max_v = v_stay; 
        end
        history(i) = v_stay;
    end
end

function is_valid = is_l0_schedule_valid(schedule, G, code_map, nodes_table)
    % 简化的L0约束检查实现
    l0_active = zeros(1, 3);  % [L0A, L0B, L0C]
    
    for i = 1:length(schedule)
        node_id = schedule(i);
        
        % 直接从nodes_table获取节点信息（更可靠）
        if nargin >= 4 && ~isempty(nodes_table)
            op = nodes_table.OpCode(node_id);
            type = nodes_table.TypeCode(node_id);
        else
            % 回退到使用G.Nodes（如果可用）
            op = G.Nodes.OpCode(node_id); 
            type = G.Nodes.TypeCode(node_id);
        end
        
        if isequal(op, code_map.op.ALLOC)
            if isequal(type, code_map.type.L0A)
                l0_active(1) = l0_active(1) + 1;
            elseif isequal(type, code_map.type.L0B)
                l0_active(2) = l0_active(2) + 1;
            elseif isequal(type, code_map.type.L0C)
                l0_active(3) = l0_active(3) + 1;
            end
            
            % 检查是否违反约束（每种L0类型最多1个同时活跃）
            if any(l0_active > 1)
                is_valid = false;
                return;
            end
            
        elseif isequal(op, code_map.op.FREE)
            if isequal(type, code_map.type.L0A)
                l0_active(1) = l0_active(1) - 1;
            elseif isequal(type, code_map.type.L0B)
                l0_active(2) = l0_active(2) - 1;
            elseif isequal(type, code_map.type.L0C)
                l0_active(3) = l0_active(3) - 1;
            end
        end
    end
    
    is_valid = true;
end
